﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ATR.cs" company="">
//   
// </copyright>
// <summary>
//   The atr.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Systemathics.FrameWork;

namespace Systemathics.Indicators
{
    [Serializable]
    public sealed class ATR : Indicator
    {
        private readonly Queue<Decimal> queue;
        private readonly RemotingLogClient remote;
        private Bar bar_t;
        private Bar bar_t_1;
        private Decimal mu;
        private Decimal TrueRange;
        private decimal a, b;

        public ATR(Instrument instr, BarType bt, int barValue, int length) : base(instr, Data.Bar, bt, barValue)
        {
            queue = new Queue<Decimal>();
            Length = length;
            mu = TrueRange = 0;
            a = new decimal((Length - 1) / (double)Length);
            b = new decimal(1 / (double)Length);
            remote = new RemotingLogClient();
        }


        public int Length { get; private set; }

        protected override void Calculate(object price)
        {
            if (price is Bar)
            {
                bar_t = price as Bar;
                if (bar_t.High != Decimal.Zero && bar_t.Low != Decimal.Zero)
                {
                    if (bar_t_1 != null)
                    {
                        TrueRange = Math.Max(Math.Max(Math.Abs(bar_t.High - bar_t.Low), Math.Abs(bar_t.High - bar_t_1.Close)), Math.Abs(bar_t.Low - bar_t_1.Close));
                        Calculate(bar_t.BeginTime, TrueRange);
                    }
                    bar_t_1 = bar_t;
                }
            }
            else
                remote.Trace(
                    new FireMessageEventArgs("Cannot calculate an ATR on Data either than Bar, check ATR consructor", DateTime.Now.TimeOfDay));
        }

        private void Calculate(DateTime time, Decimal value)
        {
            if (queue.Count < Length)
            {
                queue.Enqueue(value);
                mu = queue.Average();
            }
            else
            {
                mu = a * mu + b * value;
                Add(time, mu);
                IndicatorCalculated(this);
            }
        }
    }
}